package tcpFirmware;

import java.io.*;
import java.net.Socket;
import java.util.HashMap;

public final class ResponseBody {
    private final HashMap<String,String> header;
    private HashMap<String,String> data;
    private final Socket socket;
    private String type;
    private byte[] HeaderBytes;



    public ResponseBody(Socket socket) {
        this.header=new HashMap<>();
        this.data=new HashMap<>();
        this.socket=socket;
    }

    public final ResponseBody setRoute(String route){
        this.header.put("route",route);
        return this;
    }

    public final ResponseBody setType(String type){
        this.header.put("content-type",type);
        this.type=type;
        return this;
    }

    public final ResponseBody setHeader(String key,String value){
        this.header.put(key, value);
        return this;
    }

    public final ResponseBody setData(String key,String value){
        this.data.put(key, value);
        return this;
    }

    public final ResponseBody setData(HashMap<String,String> data1){
        this.data=data1;
        return this;
    }

    public final byte[] packed(){


        //当请求体类型为文本字符串时，封装数据
        byte[] dataBytes;
        StringBuilder dataBuilder=new StringBuilder();
        if(data.size()!=0){
            //当请求体类型为文本字符串时，封装数据
            for(String i:data.keySet()){
                dataBuilder.append(i).append(":").append(data.get(i)).append("\r\n");
            }
        }
        else {
            dataBuilder.append("data").append(":").append("null").append("\r\n");
        }
        dataBytes = dataBuilder.toString().getBytes();


        //封装首部
        StringBuilder headerBuilder = new StringBuilder();
        for(String i: header.keySet()){
            headerBuilder.append(i).append(":").append(header.get(i)).append("\r\n");
        }
        headerBuilder.append("content-length").append(":").append(dataBytes.length).append("\r\n");

        byte[] headerBytes=headerBuilder.toString().getBytes();
        this.HeaderBytes=headerBytes;

        //合并首部和数据体部

        return getRequestData(headerBytes,dataBytes);
    }

    public final byte[] packed(byte[] bytes,String filename){


        //当请求体类型为二进制文件时，封装数据


        //封装首部
        StringBuilder headerBuilder = new StringBuilder();
        for(String i: header.keySet()){
            headerBuilder.append(i).append(":").append(header.get(i)).append("\r\n");
        }
        headerBuilder.append("filename").append(":").append(filename).append("\r\n");
        headerBuilder.append("content-length").append(":").append(bytes.length).append("\r\n");

        byte[] headerBytes=headerBuilder.toString().getBytes();
        this.HeaderBytes=headerBytes;
        //合并首部和数据体部


        return getRequestData(headerBytes,bytes);
    }



    public final byte[] getRequestData(byte[] headerBytes,byte[] dataBytes){
        //偏移量占三字节，记录首部长度
        String headerLen = String.valueOf(headerBytes.length);
        if(headerLen.length()<3)headerLen="00"+headerLen;
        else if(headerLen.length()==3)headerLen='0'+headerLen;

        byte[] requestData = new byte[4+headerBytes.length+dataBytes.length];
        System.arraycopy(headerLen.getBytes(),0,requestData,0,4);
        System.arraycopy(headerBytes,0,requestData,4,headerBytes.length);
        System.arraycopy(dataBytes,0,requestData,4+headerBytes.length,dataBytes.length);
        return requestData;
    }

    public final byte[] getResponseBytes(){
        return packed();
    }

    public final byte[] getResponseBytes(byte[] Bytes,String filename){
        return packed(Bytes,filename);
    }

    public final void sendResponse() throws IOException {
        OutputStream outputStream = socket.getOutputStream();
        if (type.equals(Type.text.type)){outputStream.write(getResponseBytes());outputStream.flush();}
    }

    public final void sendResponse(byte[] fileBytes,String filename) throws IOException {
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(getResponseBytes(fileBytes,filename));outputStream.flush();
    }

    public static boolean sendNotFound(Socket socket){
        ResponseBody response = new ResponseBody(socket);
        response.setHeader("status","404").setRoute("/index").setType(Type.text.type).setData("data","null");
        try {
            response.sendResponse();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}
